アプリケーションの責務 - Noise Protocol Framework (19)
ここまではNoiseプロトコルが提供している機能について書いてきましたが、ここでは逆にNoiseプロトコルを使用するアプリケーションが持つ責務と、注意すべき事項について説明します。
暗号関数の選択
Noiseプロトコルで使用するDH関数、共通鍵暗号、ハッシュ関数は用途や必要とされるセキュリティ要件に応じて適切に選ばなくてはいけません。
DH関数としては一般的な用途であれば25519が推奨されます。
DH関数として448を使用する際は、ハッシュ関数としては512ビットのものを使用する必要があります。(SHA512またはBLAKE2b)
25519では256ビットのハッシュ関数(SHA256またはBLAKE2s)を使用できますが、セキュリティを強化したいのであれば、512ビットのものを使うこともできます。
共通鍵暗号のAESGCMは高速かつ一定時間で実行できるように実装することは困難です。
拡張性
すべてのメッセージのペイロードで(JSONやProtocol Buffersなどの)拡張可能なデータ形式を使用することが推奨されています。これにより古い実装には無視されるようなフィールドを将来追加できるようになります。
パディング
すべての暗号化メッセージのペイロードでパディングを可能にするようなデータデータ形式を使用することが推奨されています。これによりメッセージサイズに関する情報を漏洩しない実装が可能となります。これは前述の拡張可能なデータ形式を使用することで十分な場合かもしれません。
セッションの終了
アプリケーションは、一連のNoiseトランスポートメッセージが攻撃者によって切り捨てられる可能性があることを考慮しなければいけません。アプリケーションは、対話型セッションの終了または一方向のトランスポートメッセージのストリームの終了を知らせるために、トランスポートメッセージのペイロードに長さを表すフィールドまたは終了シグナルを含める必要があります。
長さフィールド
アプリケーションは、Noiseのメッセージの長さが最大65535バイトまである可能性があることを考慮して、Noiseメッセージ用のフレーミング(?)または追加の長さフィールドを扱う必要があります。明示的な"長さ"フィールドが必要な場合は、各メッセージの前に16ビットのビッグエンディアンの"長さ"フィールドを追加することが推奨されています。
ネゴシエーションデータ
アプリケーションは、ハンドシェイクの開始前および/または各ハンドシェイクメッセージの前に、何らかのネゴシエーションデータの送信をサポートすることを望むかもしれません。ネゴシエーションデータはバージョン情報や識別子のようなものを含むかもしれません。例えば、シンプルな方法としては、各ノイズハンドシェイクメッセージの先頭に1バイトの"タイプ"フィールドを送信することができます。より柔軟なアプローチはProtocol Buffersのような拡張可能な構造で送るかもしれません。ネゴシエーションデータは、重大な複雑さとロールバック攻撃のようなセキュリティ上のリスクをもたらします。
例: Lightning Network
code: lightning message structure
+-------------------------------
|2-byte encrypted message length|
+-------------------------------
| 16-byte MAC of the encrypted |
| message length |
+-------------------------------
| |
| |
| encrypted Lightning |
| message |
| |
+-------------------------------
| 16-byte MAC of the |
| Lightning message |
+-------------------------------